Abstract
Part of theR for Artists and Designers workshop course at the School of Foundation Studies, Srishti Manipal Institute of Art, Design, and Technology, Bangalore.
This RMarkdown document is part of the Generic Skills Component (GSK) of the Course of the Foundation Studies Programme at Srishti Manipal Institute of Art, Design, and Technology, Bangalore India. The material is based on A Layered Grammar of Graphics by Hadley Wickham. The course is meant for First Year students pursuing a Degree in Art and Design.
The intent of this GSK part is to build Skill in coding in R, and also appreciate R as a way to metaphorically visualize information of various kinds, using predominantly geometric figures and structures.
All RMarkdown files combine code, text, web-images, and figures developed using code. Everything is text; code chunks are enclosed in fences (```)
At the end of this Lab session, we should: - know the types and structures of spatial data and be able to work with them - understand the basics of modern spatial packages in R - be able to specify and download spatial data from the web, using R from sources such as naturalearth and Open Streep Map - plot static and interactive maps using ggplot, tmap and leaflet packages - add symbols and markers for places and regions of our own interest in these maps. - see directions for further work (e.g. maps + networks together)
The method followed will be based on PRIMM:
parameters of the code do and write comments to explain. What bells and whistles can you see?parameters code provided to understand the options available. Write comments to show what you have aimed for and achieved.The setup code chunk below brings into our coding session R packages that provide specific computational abilities and also datasets which we can use.
To reiterate: Packages and datasets are not the same thing !! Packages are (small) collections of programs. Datasets are just….information.
We will take small steps in making maps using just two of the several map making packages in R.
The steps we will use are:
prettymapr or similar..)osmdataosmplot, tmap and also with leaflet.leaflet using a variety of map data providers. Note: tmap can also do interactive maps which we will explore also.Bas. Onwards and Map-wards!!
All jargon words will be capitalized and in bold font.
Let’s get BLR data into R and see if we can plot an area of interest. Then we can order on Swiggy and…never mind.
# BLR Bounding Box
# get_bbox needs lat and lon ranges
bbox_1 <- osmplotr::get_bbox(c(77.46,12.83,77.74,13.14))
bbox_2 <- osmdata::getbb("Bangalore, India")
bbox_3 <- getbb("Jayanagar, Bangalore, India")
bbox_1
## min max
## x 77.46 77.74
## y 12.83 13.14
bbox_2
## min max
## x 77.46010 77.78405
## y 12.83401 13.14366
bbox_3
## min max
## x 77.56242 77.60242
## y 12.90927 12.94927
We will use the smaller bbox_3 from the above, to ensure we have smaller data downloads!
Within our bbox for BLR, we want to download diverse kinds of FEATURE data. Remember that a FEATURE This is done using the osmplotr::extract_osm_objects() command. The main parameters for this command are:
See OSM Tags for a nice visual description of popular tags that we can use. Useful keys include:
For example see: tag : highway
We will get the map data from OSM and then save it avoid repeated downloads. So, please copy/paste and run the following commands in your console. Do not run these commands too many times, UNLESS you have changed your bbox extent.
dat_B <- extract_osm_objects (key = "building", bbox = bbox_3)
## Issuing query to Overpass API ...
## Rate limit: 0
## Query complete!
## converting OSM data to sf format
dat_H <- extract_osm_objects (key = 'highway', bbox = bbox_3)
## Issuing query to Overpass API ...
## Rate limit: 0
## Error in curl::curl_fetch_memory(url, handle = handle): schannel: failed to receive handshake, SSL/TLS connection failed
## Request failed [ERROR]. Retrying in 1 seconds...
## Query complete!
## converting OSM data to sf format
dat_P <- extract_osm_objects (key = 'park', bbox = bbox_3)
## Issuing query to Overpass API ...
## Error in curl::curl_fetch_memory(url, handle = handle): schannel: failed to receive handshake, SSL/TLS connection failed
## Request failed [ERROR]. Retrying in 1 seconds...
## Rate limit: 0
## Error in curl::curl_fetch_memory(url, handle = handle): schannel: failed to receive handshake, SSL/TLS connection failed
## Request failed [ERROR]. Retrying in 1 seconds...
## Request failed [500]. Retrying in 3.9 seconds...
## Query complete!
## converting OSM data to sf format
dat_G <- extract_osm_objects (key = 'landuse', value = 'grass', bbox = bbox_3)
## Issuing query to Overpass API ...
## Rate limit: 0
## Request failed [504]. Retrying in 1.5 seconds...
## Query complete!
## converting OSM data to sf format
dat_T <- extract_osm_objects (key = 'natural', value = 'tree', bbox = bbox_3)
## Issuing query to Overpass API ...
## Rate limit: 0
## Query complete!
## converting OSM data to sf format
write_sf(dat_B, dsn = "dat_B.gpkg", append = FALSE, quiet = FALSE)
## Deleting layer `dat_B' using driver `GPKG'
## Writing layer `dat_B' to data source `dat_B.gpkg' using driver `GPKG'
## Writing 34642 features with 81 fields and geometry type Polygon.
write_sf(dat_P, dsn = "dat_P.gpkg", append = FALSE, quiet = FALSE)
## Deleting layer `dat_P' using driver `GPKG'
## Writing layer `dat_P' to data source `dat_P.gpkg' using driver `GPKG'
## Writing 57 features with 23 fields and geometry type Polygon.
write_sf(dat_G, dsn = "dat_G.gpkg", append = FALSE,quiet = FALSE)
## Deleting layer `dat_G' using driver `GPKG'
## Writing layer `dat_G' to data source `dat_G.gpkg' using driver `GPKG'
## Writing 2 features with 2 fields and geometry type Polygon.
write_sf(dat_T, dsn = "dat_T.gpkg", append = FALSE,quiet = FALSE)
## Deleting layer `dat_T' using driver `GPKG'
## Writing layer `dat_T' to data source `dat_T.gpkg' using driver `GPKG'
## Writing 146 features with 8 fields and geometry type Point.
##
# write_sf(dat_H, dsn = "dat_H.gpkg", append = FALSE, quiet = FALSE)
Yes, the write_sf(dat_H) does not seem to work. This is something we need to research and understand. But at least all the other files are saved locally. We will comment it out for now!
Always work from here to avoid repeated downloads from OSM.
dat_B <- st_read("./dat_B.gpkg")
## Reading layer `dat_B' from data source
## `C:\Users\Arvind\My Drive\R work\MyWebsites\R-for-Artists-and-Designers\static\labs\dat_B.gpkg'
## using driver `GPKG'
## Simple feature collection with 34642 features and 81 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: 77.56221 ymin: 12.90906 xmax: 77.60373 ymax: 12.9497
## Geodetic CRS: WGS 84
dat_P <- read_sf("./dat_P.gpkg")
dat_G <- read_sf("./dat_G.gpkg")
dat_T <- read_sf("./dat_T.gpkg")
# How many buildings?
nrow(dat_B)
## [1] 34642
dat_B$geometry
## NULL
class(dat_B$geometry)
## [1] "NULL"
So dat_B has 34642 buildings and their geometry is naturally a POLYGON type of geometry column.
Do this check for all the other spatial data, in the code chunk below. What kind of geometry column does each dataset have?
osm_structures returns a data.frame of OSM structure types, associated key-value pairs, unique suffices which may be appended to data structures for storage purposes, and suggested colours.
osmplotr::osm_structures()
## structure key value suffix cols
## 1 building building BU #646464FF
## 2 amenity amenity A #787878FF
## 3 waterway waterway W #646478FF
## 4 grass landuse grass G #64A064FF
## 5 natural natural N #647864FF
## 6 park leisure park P #647864FF
## 7 highway highway H #000000FF
## 8 boundary boundary BO #C8C8C8FF
## 9 tree natural tree T #64A064FF
## 10 background gray20
We could quickly plot this using the package osmplotr. However, in my ( i.e. Arvind’s opinion ) it is not as flexible as other packages. Maybe I need to study it in more detail.
So we will continue with ggplot and geom_sf() :
blr_map <- ggplot() +
geom_sf(data = dat_B, colour = "orange") + # POLYGONS
geom_sf(data = dat_H, col = "gray20") + # LINES
geom_sf(data = dat_G, col = "darkseagreen1") + # POLYGONS
geom_sf(data = dat_P, col = "darkseagreen") + # POLYGONS
geom_sf(data = dat_T, col = "green") # POINTS
blr_map
Note how geom_sf is capable of handling any geometry in the sfc column !!
geom_sf()is an unusual geom because it will draw different geometric objects depending on what simple features are present in the data: you can get points, lines, or polygons.
So there, we have our first map!
tmap packageWe can also create a map using a package called tmap. Here we also have the option of making the map interactive.
tmap plots are made with code in “groups”: each group starts with a tm_shape() command.
# Group-1
tm_shape(dat_B) +
tm_fill(col = "mediumblue") +
#Group-2
tm_shape(dat_H) +
tm_lines(col = "gold") +
#Group-3
tm_shape(dat_G) +
tm_polygons(col = "limegreen") +
#Group-4
tm_shape(dat_P) +
tm_polygons(col = "limegreen") +
#Group-5
tm_shape(dat_T) +
tm_dots(col = "green")
How do we make this map interactive? One more line of code !! Add this line in your console and then run the above chunk again
tmap_mode(“view”)
tmapLet’s plot a first map using datasets built into tmap.
tmap has a few built-in spatial datasets: World and metro, rivers, land and a few others. Check help on these.
data("World")
head(World, n = 3)
## Simple feature collection with 3 features and 15 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 11.6401 ymin: -17.93064 xmax: 75.15803 ymax: 42.68825
## Geodetic CRS: WGS 84
## iso_a3 name sovereignt continent area pop_est pop_est_dens
## 1 AFG Afghanistan Afghanistan Asia 652860 [km^2] 28400000 43.50090
## 2 AGO Angola Angola Africa 1246700 [km^2] 12799293 10.26654
## 3 ALB Albania Albania Europe 27400 [km^2] 3639453 132.82675
## economy income_grp gdp_cap_est life_exp
## 1 7. Least developed region 5. Low income 784.1549 59.668
## 2 7. Least developed region 3. Upper middle income 8617.6635 NA
## 3 6. Developing region 4. Lower middle income 5992.6588 77.347
## well_being footprint inequality HPI geometry
## 1 3.8 0.79 0.4265574 20.22535 MULTIPOLYGON (((61.21082 35...
## 2 NA NA NA NA MULTIPOLYGON (((16.32653 -5...
## 3 5.5 2.21 0.1651337 36.76687 MULTIPOLYGON (((20.59025 41...
We have several 14 attribute variables in World. Attribute variables such as gdp_cap_est, HPI are numeric. Others such as income_grp appear to be factors. iso_a3 is the standard three letter name for the country.
data("metro")
head(metro, n = 3)
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## Simple feature collection with 3 features and 12 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: 3.04197 ymin: -8.83682 xmax: 69.17246 ymax: 36.7525
## Geodetic CRS: WGS 84
## name name_long iso_a3 pop1950 pop1960 pop1970 pop1980 pop1990
## 2 Kabul Kabul AFG 170784 285352 471891 977824 1549320
## 8 Algiers El Djazair (Algiers) DZA 516450 871636 1281127 1621442 1797068
## 13 Luanda Luanda AGO 138413 219427 459225 771349 1390240
## pop2000 pop2010 pop2020 pop2030 geometry
## 2 2401109 3722320 5721697 8279607 POINT (69.17246 34.52889)
## 8 2140577 2432023 2835218 3404575 POINT (3.04197 36.7525)
## 13 2591388 4508434 6836849 10428756 POINT (13.23432 -8.83682)
Here too we have attribute variables for the metros, and they seem predominantly numeric. Again iso_a3 is the three letter name for the city.
tmap_mode("plot") # Making this a static plot
## tmap mode set to plotting
# Group 1
tm_shape(World) + # dataset = World.
tm_polygons("HPI") + # Colour polygons by HPI numeric variable
# Note the "+" sign continuation
# Group 2
tm_shape(metro) + # dataset = metro
tm_bubbles(size = "pop2030",
col = "red")
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
# Plot cities as bubbles
# Size proportional to numeric variable `pop2030`
tmap_mode("view") # Change to Interactive
## tmap mode set to interactive viewing
# Let's use WaterColor Map this time!!
tm_tiles("Stamen.Watercolor") + # Watercolor map only with interactive
tm_shape(World) +
tm_polygons("HPI") +
tm_shape(metro) +
tm_bubbles(size = "pop2030",
col = "red")
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## Legend for symbol sizes not available in view mode.
rnaturalearthindia <-
ne_states(country = "india",
geounit = "india",
returnclass = "sf")
india_neighbours <-
ne_states(country = (c("india", "sri lanka", "pakistan",
"afghanistan", "nepal","bangladesh")
),
returnclass = "sf")
Let’s look at the attribute variable columns to colour our graph and to shape our symbols:
names(india)
## [1] "featurecla" "scalerank" "adm1_code" "diss_me" "iso_3166_2"
## [6] "wikipedia" "iso_a2" "adm0_sr" "name" "name_alt"
## [11] "name_local" "type" "type_en" "code_local" "code_hasc"
## [16] "note" "hasc_maybe" "region" "region_cod" "provnum_ne"
## [21] "gadm_level" "check_me" "datarank" "abbrev" "postal"
## [26] "area_sqkm" "sameascity" "labelrank" "name_len" "mapcolor9"
## [31] "mapcolor13" "fips" "fips_alt" "woe_id" "woe_label"
## [36] "woe_name" "latitude" "longitude" "sov_a3" "adm0_a3"
## [41] "adm0_label" "admin" "geonunit" "gu_a3" "gn_id"
## [46] "gn_name" "gns_id" "gns_name" "gn_level" "gn_region"
## [51] "gn_a1_code" "region_sub" "sub_code" "gns_level" "gns_lang"
## [56] "gns_adm1" "gns_region" "min_label" "max_label" "min_zoom"
## [61] "wikidataid" "name_ar" "name_bn" "name_de" "name_en"
## [66] "name_es" "name_fr" "name_el" "name_hi" "name_hu"
## [71] "name_id" "name_it" "name_ja" "name_ko" "name_nl"
## [76] "name_pl" "name_pt" "name_ru" "name_sv" "name_tr"
## [81] "name_vi" "name_zh" "ne_id" "geometry"
names(india_neighbours)
## [1] "featurecla" "scalerank" "adm1_code" "diss_me" "iso_3166_2"
## [6] "wikipedia" "iso_a2" "adm0_sr" "name" "name_alt"
## [11] "name_local" "type" "type_en" "code_local" "code_hasc"
## [16] "note" "hasc_maybe" "region" "region_cod" "provnum_ne"
## [21] "gadm_level" "check_me" "datarank" "abbrev" "postal"
## [26] "area_sqkm" "sameascity" "labelrank" "name_len" "mapcolor9"
## [31] "mapcolor13" "fips" "fips_alt" "woe_id" "woe_label"
## [36] "woe_name" "latitude" "longitude" "sov_a3" "adm0_a3"
## [41] "adm0_label" "admin" "geonunit" "gu_a3" "gn_id"
## [46] "gn_name" "gns_id" "gns_name" "gn_level" "gn_region"
## [51] "gn_a1_code" "region_sub" "sub_code" "gns_level" "gns_lang"
## [56] "gns_adm1" "gns_region" "min_label" "max_label" "min_zoom"
## [61] "wikidataid" "name_ar" "name_bn" "name_de" "name_en"
## [66] "name_es" "name_fr" "name_el" "name_hi" "name_hu"
## [71] "name_id" "name_it" "name_ja" "name_ko" "name_nl"
## [76] "name_pl" "name_pt" "name_ru" "name_sv" "name_tr"
## [81] "name_vi" "name_zh" "ne_id" "geometry"
# Look only at attributes
india %>% st_drop_geometry() %>% head()
## featurecla scalerank adm1_code diss_me iso_3166_2 wikipedia iso_a2
## 3 Admin-1 scale rank 2 IND-3264 3264 IN-GJ <NA> IN
## 16 Admin-1 scale rank 2 IND-2431 2431 IN-JK <NA> IN
## 47 Admin-1 scale rank 2 IND-3299 3299 IN-AR <NA> IN
## 576 Admin-1 scale rank 2 IND-2477 2477 IN-AS <NA> IN
## 578 Admin-1 scale rank 2 IND-3259 3259 IN-SK <NA> IN
## 581 Admin-1 scale rank 2 IND-3257 3257 IN-WB <NA> IN
## adm0_sr name
## 3 1 Gujarat
## 16 1 Jammu and Kashmir
## 47 1 Arunachal Pradesh
## 576 1 Assam
## 578 1 Sikkim
## 581 4 West Bengal
## name_alt
## 3 <NA>
## 16 <NA>
## 47 Agence de la Frontisre du Nord-Est(French-obsolete)|North East Frontier Agency
## 576 <NA>
## 578 <NA>
## 581 Bangla|Bengala Occidentale|Bengala Ocidental|Bengale occidental
## name_local type type_en code_local code_hasc note hasc_maybe region
## 3 <NA> <NA> <NA> <NA> IN.GJ <NA> <NA> West
## 16 <NA> State State <NA> IN.JK <NA> <NA> North
## 47 <NA> State State <NA> IN.AR <NA> <NA> Northeast
## 576 <NA> State State <NA> IN.AS <NA> <NA> Northeast
## 578 <NA> State State <NA> IN.SK <NA> <NA> East
## 581 <NA> State State <NA> IN.WB <NA> <NA> East
## region_cod provnum_ne gadm_level check_me datarank abbrev postal area_sqkm
## 3 <NA> 20064 1 20 1 <NA> <NA> 0
## 16 <NA> 20066 1 20 1 <NA> JK 0
## 47 <NA> 20045 1 20 1 <NA> AR 0
## 576 <NA> 20049 1 20 1 <NA> AS 0
## 578 <NA> 20058 1 20 1 <NA> SK 0
## 581 <NA> 20010 1 20 1 <NA> WB 0
## sameascity labelrank name_len mapcolor9 mapcolor13 fips fips_alt woe_id
## 3 NA 2 7 2 2 IN32 <NA> 2345743
## 16 NA 2 17 2 2 IN12 <NA> 2345746
## 47 NA 2 17 2 2 IN30 <NA> 2345763
## 576 NA 2 5 2 2 IN03 <NA> 2345741
## 578 NA 2 6 2 2 IN29 <NA> 2345762
## 581 NA 2 11 2 2 IN28 <NA> 2345761
## woe_label woe_name latitude longitude sov_a3
## 3 Gujarat, IN, India Gujarat 22.7501 71.3013 IND
## 16 Jammu and Kashmir, IN, India Jammu and Kashmir 33.9658 76.6395 IND
## 47 Arunachal Pradesh, IN, India Arunachal Pradesh 28.4056 94.4673 IND
## 576 Assam, IN, India Assam 26.3302 92.9929 IND
## 578 Sikkim, IN, India Sikkim 27.5709 88.4482 IND
## 581 West Bengal, IN, India West Bengal 23.0523 87.7289 IND
## adm0_a3 adm0_label admin geonunit gu_a3 gn_id gn_name
## 3 IND 2 India India IND 1270770 State of Gujarat
## 16 IND 5 India India IND 1269320 State of Jammu and Kashmir
## 47 IND 5 India India IND 1278341 State of Arunachal Pradesh
## 576 IND 2 India India IND 1278253 State of Assam
## 578 IND 2 India India IND 1256312 State of Sikkim
## 581 IND 2 India India IND 1252881 State of West Bengal
## gns_id gns_name gn_level gn_region gn_a1_code
## 3 -2096768 Gujarat, State of 1 <NA> IN.09
## 16 -2098229 Jammu and Kashmir, State of 1 <NA> IN.12
## 47 -2089163 Arunachal Pradesh, State of 1 <NA> IN.30
## 576 -2089251 Assam, State of 1 <NA> IN.03
## 578 -2111292 Sikkim, State of 1 <NA> IN.29
## 581 -2114741 West Bengal, State of 1 <NA> IN.28
## region_sub sub_code gns_level gns_lang gns_adm1 gns_region min_label
## 3 <NA> <NA> 1 nld IN09 <NA> 4.6
## 16 <NA> <NA> 1 nld IN12 <NA> 4.6
## 47 <NA> <NA> 1 nld IN30 <NA> 4.6
## 576 <NA> <NA> 1 nld IN03 <NA> 4.6
## 578 <NA> <NA> 1 nld IN29 <NA> 4.6
## 581 <NA> <NA> 1 nld IN28 <NA> 4.6
## max_label min_zoom wikidataid name_ar name_bn name_de
## 3 10.1 4.6 Q1061 <NA> <NA> Gujarat
## 16 10.1 4.6 Q1180 <NA> <NA> Jammu und Kashmir
## 47 10.1 4.6 Q1162 <NA> <NA> Arunachal Pradesh
## 576 10.1 4.6 Q1164 <NA> <NA> Assam
## 578 10.1 4.6 Q1505 <NA> <NA> Sikkim
## 581 10.1 4.6 Q1356 <NA> <NA> Westbengalen
## name_en name_es name_fr name_el name_hi
## 3 Gujarat Guyarat Gujarat <NA> <NA>
## 16 Jammu and Kashmir Jammu y Cachemira Jammu-et-Cachemire <NA> <NA>
## 47 Arunachal Pradesh Arunachal Pradesh Arunachal Pradesh <NA> <NA>
## 576 Assam Assam Assam <NA> <NA>
## 578 Sikkim Sikkim Sikkim <NA> <NA>
## 581 West Bengal Bengala Occidental Bengale-Occidental <NA> <NA>
## name_hu name_id name_it name_ja name_ko
## 3 Gudzsarát Gujarat Gujarat <NA> <NA>
## 16 Dzsammu és Kasmír Jammu dan Kashmir Jammu e Kashmir <NA> <NA>
## 47 Arunácsal Prades Arunachal Pradesh Arunachal Pradesh <NA> <NA>
## 576 Asszám Assam Assam <NA> <NA>
## 578 Szikkim Sikkim Sikkim <NA> <NA>
## 581 Nyugat-Bengál Benggala Barat Bengala Occidentale <NA> <NA>
## name_nl name_pl name_pt name_ru
## 3 Gujarat Gudzarat Gujarate <NA>
## 16 Jammu en Kasjmir Dzammu i Kaszmir Jammu e Caxemira <NA>
## 47 Arunachal Pradesh Arunachal Pradesh Arunachal Pradesh <NA>
## 576 Assam Asam Assam <NA>
## 578 Sikkim Sikkim Siquim <NA>
## 581 West-Bengalen Bengal Zachodni Bengala Ocidental <NA>
## name_sv name_tr name_vi name_zh ne_id
## 3 Gujarat Gucerat Gujarat <NA> 1159314179
## 16 Jammu och Kashmir Cemmu ve Kesmir Jammu và Kashmir <NA> 1159311911
## 47 Arunachal Pradesh Arunaçhal Pradesh Arunachal Pradesh <NA> 1159315223
## 576 Assam Assam Assam <NA> 1159311865
## 578 Sikkim Sikkim Sikkim <NA> 1159314169
## 581 Västbengalen Bati Bengal Tây Bengal <NA> 1159313981
india_neighbours%>% st_drop_geometry() %>% head()
## featurecla scalerank adm1_code diss_me iso_3166_2 wikipedia iso_a2
## 2 Admin-1 scale rank 3 PAK-1114 1114 PK-SD <NA> PK
## 3 Admin-1 scale rank 2 IND-3264 3264 IN-GJ <NA> IN
## 16 Admin-1 scale rank 2 IND-2431 2431 IN-JK <NA> IN
## 38 Admin-1 scale rank 3 PAK-1111 1111 PK-GB <NA> PK
## 39 Admin-1 scale rank 3 PAK-1109 1109 PK-JK <NA> PK
## 40 Admin-1 scale rank 3 PAK-1113 1113 PK-PB <NA> PK
## adm0_sr name name_alt name_local
## 2 1 Sind Sindh <NA>
## 3 1 Gujarat <NA> <NA>
## 16 1 Jammu and Kashmir <NA> <NA>
## 38 1 Northern Areas <NA> <NA>
## 39 1 Azad Kashmir Kashmir <NA>
## 40 1 Punjab Pendjab|Penjab <NA>
## type type_en code_local code_hasc
## 2 Province Province <NA> PK.SD
## 3 <NA> <NA> <NA> IN.GJ
## 16 State State <NA> IN.JK
## 38 Centrally Administered Area Centrally Administered Area <NA> PK.NA
## 39 Centrally Administered Area Centrally Administered Area <NA> PK.JK
## 40 Province Province <NA> PK.PB
## note hasc_maybe
## 2 <NA> <NA>
## 3 <NA> <NA>
## 16 <NA> <NA>
## 38 <NA> <NA>
## 39 Should be divided into 8 districts. Check with Wikipedia <NA>
## 40 <NA> PK.IS|PAK-PNJ
## region region_cod provnum_ne gadm_level check_me datarank abbrev postal
## 2 <NA> <NA> 2 1 20 2 <NA> SD
## 3 West <NA> 20064 1 20 1 <NA> <NA>
## 16 North <NA> 20066 1 20 1 <NA> JK
## 38 <NA> <NA> 4 1 20 2 <NA> NA
## 39 <NA> <NA> 3 1 20 2 <NA> JK
## 40 <NA> <NA> 5 1 20 2 <NA> PB
## area_sqkm sameascity labelrank name_len mapcolor9 mapcolor13 fips fips_alt
## 2 0 NA 3 4 3 11 PK05 <NA>
## 3 0 NA 2 7 2 2 IN32 <NA>
## 16 0 NA 2 17 2 2 IN12 <NA>
## 38 0 NA 3 14 3 11 PK07 <NA>
## 39 0 NA 3 12 3 11 PK06 <NA>
## 40 0 NA 3 6 3 11 PK04 PK08
## woe_id woe_label woe_name latitude longitude
## 2 2346499 Sindh, PK, Pakistan Sind 26.3734 68.8685
## 3 2345743 Gujarat, IN, India Gujarat 22.7501 71.3013
## 16 2345746 Jammu and Kashmir, IN, India Jammu and Kashmir 33.9658 76.6395
## 38 2346501 Northern Areas, PK, Pakistan Northern Areas 35.7864 74.9848
## 39 2346500 Azad Kashmir, PK, Pakistan Azad Kashmir 33.8680 73.8036
## 40 2346498 Punjab, PK, Pakistan Punjab 31.3589 72.3449
## sov_a3 adm0_a3 adm0_label admin geonunit gu_a3 gn_id
## 2 PAK PAK 2 Pakistan Pakistan PAK 1164807
## 3 IND IND 2 India India IND 1270770
## 16 IND IND 5 India India IND 1269320
## 38 PAK PAK 5 Pakistan Pakistan PAK 1168878
## 39 PAK PAK 5 Pakistan Pakistan PAK 1184196
## 40 PAK PAK 2 Pakistan Pakistan PAK 1167710
## gn_name gns_id gns_name gn_level
## 2 Sindh -2774813 Sindh 1
## 3 State of Gujarat -2096768 Gujarat, State of 1
## 16 State of Jammu and Kashmir -2098229 Jammu and Kashmir, State of 1
## 38 Northern Areas 0 <NA> 1
## 39 Azad Kashmir 0 <NA> 1
## 40 Punjab -2771862 Punjab 1
## gn_region gn_a1_code region_sub sub_code gns_level gns_lang gns_adm1
## 2 <NA> PK.05 <NA> <NA> 1 rus PK05
## 3 <NA> IN.09 <NA> <NA> 1 nld IN09
## 16 <NA> IN.12 <NA> <NA> 1 nld IN12
## 38 <NA> PK.07 <NA> <NA> 0 <NA> <NA>
## 39 <NA> PK.06 <NA> <NA> 0 <NA> <NA>
## 40 <NA> PK.04 <NA> <NA> 1 eng PK04
## gns_region min_label max_label min_zoom wikidataid name_ar name_bn
## 2 <NA> 5.0 10.5 5.0 Q37211 <NA> <NA>
## 3 <NA> 4.6 10.1 4.6 Q1061 <NA> <NA>
## 16 <NA> 4.6 10.1 4.6 Q1180 <NA> <NA>
## 38 <NA> 5.0 10.5 5.0 Q200697 <NA> <NA>
## 39 <NA> 5.0 10.5 5.0 Q200130 <NA> <NA>
## 40 <NA> 5.0 10.5 5.0 Q4478 <NA> <NA>
## name_de name_en name_es
## 2 Sindh Sindh Sindh
## 3 Gujarat Gujarat Guyarat
## 16 Jammu und Kashmir Jammu and Kashmir Jammu y Cachemira
## 38 Gilgit-Baltistan Gilgit-Baltistan Gilgit-Baltistán
## 39 Asad Jammu und Kaschmir Azad Kashmir Azad Cachemira
## 40 Punjab Punjab Panyab
## name_fr name_el name_hi name_hu name_id
## 2 Sind <NA> <NA> Szindh Sindh
## 3 Gujarat <NA> <NA> Gudzsarát Gujarat
## 16 Jammu-et-Cachemire <NA> <NA> Dzsammu és Kasmír Jammu dan Kashmir
## 38 Gilgit-Baltistan <NA> <NA> <NA> Gilgit–Baltistan
## 39 Azad Cachemire <NA> <NA> <NA> Azad Kashmir
## 40 Pendjab <NA> <NA> Pandzsáb Punjab
## name_it name_ja name_ko name_nl name_pl
## 2 Sindh <NA> <NA> Sindh Sindh
## 3 Gujarat <NA> <NA> Gujarat Gudzarat
## 16 Jammu e Kashmir <NA> <NA> Jammu en Kasjmir Dzammu i Kaszmir
## 38 Gilgit-Baltistan <NA> <NA> Gilgit-Baltistan Gilgit-Baltistan
## 39 Azad Kashmir <NA> <NA> Azad Kasjmir Azad Dzammu i Kaszmir
## 40 Punjab <NA> <NA> Punjab Pendzab
## name_pt name_ru name_sv name_tr name_vi
## 2 Sind <NA> Sindh Sind Eyaleti Sindh
## 3 Gujarate <NA> Gujarat Gucerat Gujarat
## 16 Jammu e Caxemira <NA> Jammu och Kashmir Cemmu ve Kesmir Jammu và Kashmir
## 38 Gilgit-Baltistão <NA> Gilgit-Baltistan Gilgit-Baltistan Gilgit-Baltistan
## 39 Caxemira Livre <NA> Azad Kashmir Azad Kesmir Azad Kashmir
## 40 Punjab <NA> Punjab Pencap Eyaleti Punjab
## name_zh ne_id
## 2 <NA> 1159309351
## 3 <NA> 1159314179
## 16 <NA> 1159311911
## 38 <NA> 1159310545
## 39 <NA> 1159310503
## 40 <NA> 1159309349
tmap_mode("view")
## tmap mode set to interactive viewing
# Plot the Neighbours
tm_shape(World %>% dplyr::filter(iso_a3 %in% c("IND", "AFG", "PAK", "NPL", "BGD", "LKA"))) +
tm_borders() +
# Plot India
tm_shape(india) +
tm_polygons("name",legend.show = FALSE) +
# Plot Neighbours
tm_shape(india_neighbours) +
tm_polygons("name", legend.show = FALSE) +
# Plot the cities in India alone
tm_shape(metro %>% dplyr::filter(iso_a3 == "IND")) +
tm_dots(size = "pop2020",legend.size.show = FALSE) +
tm_layout(legend.show = FALSE) +
tm_credits("Geographical Boundaries are not accurate",
size = 0.5,
position = "right") +
tm_compass(position = c("right", "top")) +
tm_scale_bar(position = "left") +
tmap_style("watercolor")
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## tmap style set to "watercolor"
## other available styles are: "white", "gray", "natural", "cobalt", "col_blind", "albatross", "beaver", "bw", "classic"
## Credits not supported in view mode.
## Compass not supported in view mode.
## Warning: Number of levels of the variable "name" is 35, which is
## larger than max.categories (which is 30), so levels are combined. Set
## tmap_options(max.categories = 35) in the layer function to show all levels.
## Warning: Number of levels of the variable "name" is 112, which is
## larger than max.categories (which is 30), so levels are combined. Set
## tmap_options(max.categories = 112) in the layer function to show all levels.
#Try other map styles
#cobalt #gray #white #col_blind #beaver #classic #watercolor #albatross #bw
Can you try to download a map area of your home town and plot it as we have above?
Is it time to order on Swiggy…
Let us adding interesting places to our map: say based on your favourite restaurants etc. We need restaurant data: lat/long + name + maybe type of restaurant. This can be manually created ( like all of OSMdata ) or if it is already there we can download using key-value pairs in our OSM data query.
dat_R <- extract_osm_objects(bbox = bbox_3,
key = "amenity",
value = "restaurant",
return_type = "point") #<<
## Issuing query to Overpass API ...
## Rate limit: 0
## Query complete!
## converting OSM data to sf format
# Save the data for future use
write_sf(dat_R, dsn = "dat_R.gpkg",append = FALSE, quiet = FALSE)
## Deleting layer `dat_R' using driver `GPKG'
## Writing layer `dat_R' to data source `dat_R.gpkg' using driver `GPKG'
## Writing 206 features with 33 fields and geometry type Point.
Note the return_type parameter: we want the location and not the building in which the restaurant is!!
dat_R <- st_read("./dat_R.gpkg")
## Reading layer `dat_R' from data source
## `C:\Users\Arvind\My Drive\R work\MyWebsites\R-for-Artists-and-Designers\static\labs\dat_R.gpkg'
## using driver `GPKG'
## Simple feature collection with 206 features and 33 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: 77.56373 ymin: 12.9105 xmax: 77.60104 ymax: 12.94917
## Geodetic CRS: WGS 84
# How many restaurants have we got?
dat_R %>% nrow()
## [1] 206
names(dat_R)
## [1] "osm_id" "name" "addr.city"
## [4] "addr.housename" "addr.housenumber" "addr.postcode"
## [7] "addr.street" "alt_name" "amenity"
## [10] "building" "capacity" "cuisine"
## [13] "delivery" "description" "diet.vegetarian"
## [16] "email" "food" "internet_access"
## [19] "level" "name.en" "name.kn"
## [22] "note" "opening_hours" "operator"
## [25] "phone" "smoking" "source"
## [28] "takeaway" "toilets.wheelchair" "website"
## [31] "wheelchair" "wikidata" "wikipedia"
## [34] "geom"
These are the columns in the Restaurant Data
# Let's look at the `cuisine` column!
# ( I want pizza...)
dat_R$cuisine
## [1] NA
## [2] NA
## [3] "indian"
## [4] "italian"
## [5] NA
## [6] "indian"
## [7] "indian"
## [8] "regional"
## [9] "indian"
## [10] NA
## [11] NA
## [12] NA
## [13] NA
## [14] NA
## [15] NA
## [16] NA
## [17] "pizza"
## [18] NA
## [19] NA
## [20] NA
## [21] NA
## [22] NA
## [23] "regional"
## [24] "ice_cream"
## [25] "ice_cream"
## [26] NA
## [27] NA
## [28] NA
## [29] "indian"
## [30] "chinese"
## [31] NA
## [32] NA
## [33] "pizza"
## [34] NA
## [35] "burger;sandwich"
## [36] NA
## [37] "chinese"
## [38] NA
## [39] NA
## [40] NA
## [41] NA
## [42] NA
## [43] NA
## [44] NA
## [45] NA
## [46] NA
## [47] NA
## [48] "indian"
## [49] NA
## [50] "italian"
## [51] "regional"
## [52] NA
## [53] "indian"
## [54] "indian"
## [55] "italian"
## [56] "regional"
## [57] "indian"
## [58] "chinese"
## [59] "indian"
## [60] NA
## [61] "indian"
## [62] "indian"
## [63] "indian"
## [64] NA
## [65] "indian"
## [66] NA
## [67] NA
## [68] "ice_cream"
## [69] "pizza"
## [70] NA
## [71] "South_Indian"
## [72] "regional"
## [73] "regional"
## [74] NA
## [75] NA
## [76] NA
## [77] NA
## [78] NA
## [79] NA
## [80] NA
## [81] NA
## [82] NA
## [83] NA
## [84] NA
## [85] NA
## [86] NA
## [87] NA
## [88] NA
## [89] NA
## [90] NA
## [91] NA
## [92] NA
## [93] NA
## [94] NA
## [95] NA
## [96] "Multi-cuisne"
## [97] "South_India"
## [98] "indian"
## [99] "indian"
## [100] "chicken;regional"
## [101] NA
## [102] "arab"
## [103] "indian"
## [104] NA
## [105] NA
## [106] NA
## [107] "regional"
## [108] "regional"
## [109] NA
## [110] "regional"
## [111] "regional"
## [112] "regional"
## [113] "regional"
## [114] "indian;seafood;fine_dining"
## [115] "indian"
## [116] "indian"
## [117] "indian"
## [118] "regional"
## [119] "regional"
## [120] "italian"
## [121] "regional"
## [122] "regional"
## [123] "regional"
## [124] "regional"
## [125] "regional"
## [126] "regional"
## [127] "regional"
## [128] "regional"
## [129] "regional"
## [130] "regional"
## [131] "regional"
## [132] "regional"
## [133] "fast_food"
## [134] "indian"
## [135] "regional"
## [136] "italian"
## [137] "regional"
## [138] "regional"
## [139] "regional"
## [140] "regional"
## [141] "regional"
## [142] "regional"
## [143] "italian"
## [144] "fast_food"
## [145] "regional"
## [146] "fast_food"
## [147] "regional"
## [148] "chinese"
## [149] NA
## [150] "regional"
## [151] "regional"
## [152] "regional"
## [153] "regional"
## [154] "regional"
## [155] "regional"
## [156] "regional"
## [157] "regional"
## [158] "regional"
## [159] "regional"
## [160] "regional"
## [161] "regional"
## [162] "regional"
## [163] "regional"
## [164] "regional"
## [165] "regional"
## [166] "regional"
## [167] "regional"
## [168] "regional"
## [169] "regional"
## [170] "kebab;grill"
## [171] "chicken"
## [172] "chinese;sandwich;tea;indian;coffee_shop"
## [173] NA
## [174] "indian,_japanese"
## [175] "italian"
## [176] NA
## [177] NA
## [178] NA
## [179] NA
## [180] NA
## [181] NA
## [182] NA
## [183] NA
## [184] NA
## [185] NA
## [186] NA
## [187] NA
## [188] NA
## [189] NA
## [190] NA
## [191] NA
## [192] NA
## [193] NA
## [194] NA
## [195] NA
## [196] NA
## [197] NA
## [198] NA
## [199] "indian"
## [200] NA
## [201] NA
## [202] NA
## [203] NA
## [204] NA
## [205] NA
## [206] "indian;regional"
So let us plot the restaurants as POINTs using the dat-R data we have downloaded. The cuisine attribute looks interesting; let us colour the POINT based on the cuisine offered at that restaurant.
cuisine attribute:
cuisine variable has more than one entry for a given restaurant. We use tidyr::separate() to make multiple columns out of the cuisine column and retain the first one only. Since the entries are badly entered using both “;” and “,” we need to do this twice ;-()
dat_R <- dat_R %>%
drop_na(cuisine) %>% # Knock off nondescript restaurants
# Some have more than on classification ;-()
# Separated by semicolon or comma, so....
separate(col = cuisine, into = c("cuisine", NA, NA), sep = ";") %>%
separate(col = cuisine, into = c("cuisine", NA, NA), sep = ",")
## Warning: Expected 3 pieces. Additional pieces discarded in 1 rows [105].
## Warning: Expected 3 pieces. Missing pieces filled with `NA` in 107 rows [1, 2,
## 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...].
## Warning: Expected 3 pieces. Missing pieces filled with `NA` in 109 rows [1, 2,
## 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...].
# Finally good food?
dat_R$cuisine
## [1] "indian" "italian" "indian" "indian" "regional"
## [6] "indian" "pizza" "regional" "ice_cream" "ice_cream"
## [11] "indian" "chinese" "pizza" "burger" "chinese"
## [16] "indian" "italian" "regional" "indian" "indian"
## [21] "italian" "regional" "indian" "chinese" "indian"
## [26] "indian" "indian" "indian" "indian" "ice_cream"
## [31] "pizza" "South_Indian" "regional" "regional" "Multi-cuisne"
## [36] "South_India" "indian" "indian" "chicken" "arab"
## [41] "indian" "regional" "regional" "regional" "regional"
## [46] "regional" "regional" "indian" "indian" "indian"
## [51] "indian" "regional" "regional" "italian" "regional"
## [56] "regional" "regional" "regional" "regional" "regional"
## [61] "regional" "regional" "regional" "regional" "regional"
## [66] "regional" "fast_food" "indian" "regional" "italian"
## [71] "regional" "regional" "regional" "regional" "regional"
## [76] "regional" "italian" "fast_food" "regional" "fast_food"
## [81] "regional" "chinese" "regional" "regional" "regional"
## [86] "regional" "regional" "regional" "regional" "regional"
## [91] "regional" "regional" "regional" "regional" "regional"
## [96] "regional" "regional" "regional" "regional" "regional"
## [101] "regional" "regional" "kebab" "chicken" "chinese"
## [106] "indian" "italian" "indian" "indian"
Now let’s plot the Restaurants as POINTs:
# http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf
#
ggplot() +
geom_sf(data = dat_B, colour = "burlywood1") +
geom_sf(data = dat_H, colour = "gray80") +
geom_sf(data = dat_R %>% drop_na(cuisine), aes(fill = cuisine), colour = "black", shape = 21) +
theme(legend.position = "right") +
labs(title = "Restaurants in South Central Bangalore",
caption = "Based on osmdata")
We could have done a (much!) better job, by combining cuisines into simpler and fewer categories, but that is for another day!!
By now we know that we can use geom_sf() multiple number of times with different datasets to create layered maps in R.
Emine Fidan, Guide to Creating Interactive Maps in R
Nikita Voevodin,R, Not the Best Practices